/******************************************************************************
 Copyright (c) 2024 Qualcomm Technologies International, Ltd.
 All Rights Reserved.
 Qualcomm Technologies International, Ltd. Confidential and Proprietary.

******************************************************************************/

/*!
@file    gatt_ots_client.h
@brief   Header file for the GATT OTS client library.

         This file provides documentation for the OTS client library
         APIs (library name: gatt_ots_client).
*/

#ifndef GATT_OTS_CLIENT_H
#define GATT_OTS_CLIENT_H

#include "csr_list.h"
#include "service_handle.h"
#include "csr_bt_gatt_lib.h"

#define OTSC_INVALID_OBJECT_UUID                            ((CsrBtUuid) {0,{0,0}})
#define OTSC_INVALID_OBJECT_ID                              NULL

/*!
    @brief Defines of the messages a client task may receive from
           OTS client library.
 */
typedef uint16                                              GattOtscMessageId;

#define GATT_OTSC_PRIM_UPSTREAM_LOWEST                      (0x0000 + CSR_PRIM_UPSTREAM)

#define GATT_OTSC_INIT_CFM                                  ((GattOtscMessageId) (0x0001 + GATT_OTSC_PRIM_UPSTREAM_LOWEST))
#define GATT_OTSC_TERMINATE_CFM                             ((GattOtscMessageId) (0x0002 + GATT_OTSC_PRIM_UPSTREAM_LOWEST))
#define GATT_OTSC_REGISTER_FOR_INDICATION_IND               ((GattOtscMessageId) (0x0003 + GATT_OTSC_PRIM_UPSTREAM_LOWEST))
#define GATT_OTSC_REGISTER_FOR_INDICATION_CFM               ((GattOtscMessageId) (0x0004 + GATT_OTSC_PRIM_UPSTREAM_LOWEST))
#define GATT_OTSC_FILTER_OBJECTS_CFM                        ((GattOtscMessageId) (0x0005 + GATT_OTSC_PRIM_UPSTREAM_LOWEST))
#define GATT_OTSC_SELECT_OBJECT_CFM                         ((GattOtscMessageId) (0x0006 + GATT_OTSC_PRIM_UPSTREAM_LOWEST))
#define GATT_OTSC_OTS_CHANNEL_OPENED_CFM                    ((GattOtscMessageId) (0x0007 + GATT_OTSC_PRIM_UPSTREAM_LOWEST))
#define GATT_OTSC_OTS_CHANNEL_CLOSED_IND                    ((GattOtscMessageId) (0x0008 + GATT_OTSC_PRIM_UPSTREAM_LOWEST))
#define GATT_OTSC_READ_OBJECT_METADATA_CFM                  ((GattOtscMessageId) (0x0009 + GATT_OTSC_PRIM_UPSTREAM_LOWEST))
#define GATT_OTSC_READ_OBJECT_CFM                           ((GattOtscMessageId) (0x000A + GATT_OTSC_PRIM_UPSTREAM_LOWEST))
#define GATT_OTSC_WRITE_OBJECT_CFM                          ((GattOtscMessageId) (0x000B + GATT_OTSC_PRIM_UPSTREAM_LOWEST))
#define GATT_OTSC_ABORT_CFM                                 ((GattOtscMessageId) (0x000C + GATT_OTSC_PRIM_UPSTREAM_LOWEST))
#define GATT_OTSC_OBJECT_CHANGED_IND                        ((GattOtscMessageId) (0x000D + GATT_OTSC_PRIM_UPSTREAM_LOWEST))

/*!
    @brief: Result codes returned from the GATT OTS client library.
            These result codes indicate the outcome of the certain request.
*/
typedef uint16                                              GattOtscResultCode;

#define GATT_OTSC_RESULT_CODE_SUCCESS                       ((GattOtscResultCode) 0x0000)
#define GATT_OTSC_RESULT_CODE_OPCODE_NOT_SUPPORTED          ((GattOtscResultCode) 0x0001)
#define GATT_OTSC_RESULT_CODE_INVALID_PARAMETER             ((GattOtscResultCode) 0x0002)
#define GATT_OTSC_RESULT_CODE_OPERATION_FAILED              ((GattOtscResultCode) 0x0003)
#define GATT_OTSC_RESULT_CODE_OUT_OF_BOUNDS                 ((GattOtscResultCode) 0x0004)
#define GATT_OTSC_RESULT_CODE_TOO_MANY_OBJECTS              ((GattOtscResultCode) 0x0005)
#define GATT_OTSC_RESULT_CODE_NO_OBJECT                     ((GattOtscResultCode) 0x0006)
#define GATT_OTSC_RESULT_CODE_OBJECT_ID_NOT_FOUND           ((GattOtscResultCode) 0x0007)
#define GATT_OTSC_RESULT_CODE_INSUFFICIENT_RESOURCES        ((GattOtscResultCode) 0x0008)
#define GATT_OTSC_RESULT_CODE_INVALID_OBJECT                ((GattOtscResultCode) 0x0009)
#define GATT_OTSC_RESULT_CODE_CHANNEL_UNAVAILABLE           ((GattOtscResultCode) 0x000A)
#define GATT_OTSC_RESULT_CODE_UNSUPPORTED_TYPE              ((GattOtscResultCode) 0x000B)
#define GATT_OTSC_RESULT_CODE_PROCEDURE_NOT_PERMITTED       ((GattOtscResultCode) 0x000C)
#define GATT_OTSC_RESULT_CODE_OBJECT_LOCKED                 ((GattOtscResultCode) 0x000D)
#define GATT_OTSC_RESULT_CODE_BUSY                          ((GattOtscResultCode) 0x000E)
#define GATT_OTSC_RESULT_CODE_TRUNCATED_DATA                ((GattOtscResultCode) 0x000F)
#define GATT_OTSC_RESULT_CODE_TIMEOUT                       ((GattOtscResultCode) 0x0010)
#define GATT_OTSC_RESULT_CODE_NOTHING_TO_ABORT              ((GattOtscResultCode) 0x0011)
#define GATT_OTSC_RESULT_CODE_OPERATION_ABORTED             ((GattOtscResultCode) 0x0012)
#define GATT_OTSC_RESULT_CODE_UNKNOWN                       ((GattOtscResultCode) 0x0013)

/*!
    @brief : Identifiers for all OTS characteristic types.
*/
typedef uint16                                              GattOtscCharacteristicsId;
#define GATT_OTSC_CHARAC_ID_NONE                            ((GattOtscCharacteristicsId) 0x0000)
#define GATT_OTSC_CHARAC_ID_OTS_FEATURE                     ((GattOtscCharacteristicsId) 0x0001)
#define GATT_OTSC_CHARAC_ID_OBJ_NAME                        ((GattOtscCharacteristicsId) 0x0002)
#define GATT_OTSC_CHARAC_ID_OBJ_TYPE                        ((GattOtscCharacteristicsId) 0x0004)
#define GATT_OTSC_CHARAC_ID_OBJ_SIZE                        ((GattOtscCharacteristicsId) 0x0008)
#define GATT_OTSC_CHARAC_ID_OBJ_FIRST_CREATED               ((GattOtscCharacteristicsId) 0x0010)
#define GATT_OTSC_CHARAC_ID_OBJ_LAST_MODIFIED               ((GattOtscCharacteristicsId) 0x0020)
#define GATT_OTSC_CHARAC_ID_OBJ_ID                          ((GattOtscCharacteristicsId) 0x0040)
#define GATT_OTSC_CHARAC_ID_OBJ_PROPERTIES                  ((GattOtscCharacteristicsId) 0x0080)
#define GATT_OTSC_CHARAC_ID_OBJ_LIST_FILTER                 ((GattOtscCharacteristicsId) 0x0100)
#define GATT_OTSC_CHARAC_ID_OBJ_CHANGED                     ((GattOtscCharacteristicsId) 0x0200)

/*!
    @brief : Different device roles which can make the object change at server.
*/
typedef uint8                                               GattOtscDeviceType;
#define GATT_OTSC_DEVICE_ROLE_SERVER                        ((GattOtscDeviceType) 0x00)
#define GATT_OTSC_DEVICE_ROLE_CLIENT                        ((GattOtscDeviceType) 0x01)

/*!
    @brief : Different types of object change may occur at server.
*/
typedef uint8                                               GattOtscObjectChangeType;
#define GATT_OTSC_OBJ_CONTENT_CHANGED                       ((GattOtscObjectChangeType) 0x01)
#define GATT_OTSC_OBJ_METADATA_CHANGED                      ((GattOtscObjectChangeType) 0x02)
#define GATT_OTSC_OBJ_CREATED                               ((GattOtscObjectChangeType) 0x04)
#define GATT_OTSC_OBJ_DELETED                               ((GattOtscObjectChangeType) 0x08)

/*!
    @brief : OTS object ID of 6 octets.
*/
#define GATT_OTSC_OBJ_SIZE                                  (6)
typedef uint8                                               GattOtscObjectId[GATT_OTSC_OBJ_SIZE];

/*!
    @brief : Values to enable & disable the CCCDs of different characteristics;
             combination of these values can be used to configure/register the
             CCCDs of multiple characteristics through a single API call.
*/
typedef uint8                                               GattOtscCharacValuesMask;
#define GATT_OTSC_ENABLE_OBJ_CHANGED_IND                    ((GattOtscCharacValuesMask) 0x0001)
#define GATT_OTSC_DISABLE_OBJ_CHANGED_IND                   ((GattOtscCharacValuesMask) 0x0002)

/*!
    @brief : Different types of objects sorting orders in the list.
*/
typedef uint16                                              GattOtscObjSortOrder;
#define GATT_OTSC_ORDER_BY_NONE                             ((GattOtscObjSortOrder) 0x00) /* No sort order to apply */
#define GATT_OTSC_ORDER_BY_OBJ_NAME_ASCENDING               ((GattOtscObjSortOrder) 0x01) /* Order the list by object name, ascending */
#define GATT_OTSC_ORDER_BY_OBJ_TYPE_ASCENDING               ((GattOtscObjSortOrder) 0x02) /* Order the list by object type, ascending */
#define GATT_OTSC_ORDER_BY_OBJ_CUR_SIZE_ASCENDING           ((GattOtscObjSortOrder) 0x03) /* Order the list by object current size, ascending */
#define GATT_OTSC_ORDER_BY_OBJ_FIRST_CREATED_TS_ASCENDING   ((GattOtscObjSortOrder) 0x04) /* Order the list by object first-created timestamp, ascending */
#define GATT_OTSC_ORDER_BY_OBJ_LAST_MODIFIED_TS_ASCENDING   ((GattOtscObjSortOrder) 0x05) /* Order the list by object last-modified timestamp, ascending */
#define GATT_OTSC_ORDER_BY_OBJ_NAME_DESCENDING              ((GattOtscObjSortOrder) 0x06) /* Order the list by object name, descending */
#define GATT_OTSC_ORDER_BY_OBJ_TYPE_DESCENDING              ((GattOtscObjSortOrder) 0x07) /* Order the list by object type, descending */
#define GATT_OTSC_ORDER_BY_OBJ_CUR_SIZE_DESCENDING          ((GattOtscObjSortOrder) 0x08) /* Order the list by object current size, descending */
#define GATT_OTSC_ORDER_BY_OBJ_FIRST_CREATED_TS_DESCENDING  ((GattOtscObjSortOrder) 0x09) /* Order the list by object first-created timestamp, descending */
#define GATT_OTSC_ORDER_BY_OBJ_LAST_MODIFIED_TS_DESCENDING  ((GattOtscObjSortOrder) 0x0A) /* Order the list by object last-modified timestamp, descending */

/*!
    @brief : Opcodes of different object list control procedures.
*/
typedef uint8                                               GattOtscObjListOpcode;
/* OLCP opcodes */
#define GATT_OTSC_OBJ_LIST_OP_FIRST                         ((GattOtscObjListOpcode) 0x01)
#define GATT_OTSC_OBJ_LIST_OP_LAST                          ((GattOtscObjListOpcode) 0x02)
#define GATT_OTSC_OBJ_LIST_OP_PREVIOUS                      ((GattOtscObjListOpcode) 0x03)
#define GATT_OTSC_OBJ_LIST_OP_NEXT                          ((GattOtscObjListOpcode) 0x04)
#define GATT_OTSC_OBJ_LIST_OP_GOTO                          ((GattOtscObjListOpcode) 0x05)
/* END : OLCP object's selection opcodes */
/* OLCP other opcodes */
#define GATT_OTSC_OBJ_LIST_OP_SORT_ORDER                    ((GattOtscObjListOpcode) 0x06)
#define GATT_OTSC_OBJ_LIST_OP_NO_OF_OBJECT                  ((GattOtscObjListOpcode) 0x07)
#define GATT_OTSC_OBJ_LIST_OP_CLR_MARKING                   ((GattOtscObjListOpcode) 0x08)
/* 0x09-0x6F : Reserved for Future Use */
/* OLCP response opcode */
#define GATT_OTSC_OBJ_LIST_OP_RESPONSE_CODE                 ((GattOtscObjListOpcode) 0x70)

/*!
    @brief : Opcodes of different object action control procedures.
*/
typedef uint8                                               GattOtscObjActionOpcode;
/* OACP opcodes */
#define GATT_OTSC_OBJ_ACTION_OP_CREATE                      ((GattOtscObjActionOpcode) 0x01)
#define GATT_OTSC_OBJ_ACTION_OP_DELETE                      ((GattOtscObjActionOpcode) 0x02)
#define GATT_OTSC_OBJ_ACTION_OP_CALCULATE_CHECKSUM          ((GattOtscObjActionOpcode) 0x03)
#define GATT_OTSC_OBJ_ACTION_OP_EXECUTE                     ((GattOtscObjActionOpcode) 0x04)
#define GATT_OTSC_OBJ_ACTION_OP_READ                        ((GattOtscObjActionOpcode) 0x05)
#define GATT_OTSC_OBJ_ACTION_OP_WRITE                       ((GattOtscObjActionOpcode) 0x06)
#define GATT_OTSC_OBJ_ACTION_OP_ABORT                       ((GattOtscObjActionOpcode) 0x07)
/* 0x08-0x5F : Reserved for Future Use */
#define GATT_OTSC_OBJ_ACTION_OP_RESPONSE_CODE               ((GattOtscObjActionOpcode) 0x60)

/*!
    @brief : Filter types a client may use to filter the objects in a list at server.
*/
typedef uint16                                              GattOtscObjectFilters;
/* No filter; let all objects pass */
#define GATT_OTSC_FILTER_NONE                              (GattOtscObjectFilters) (0x0000)
/* Name filters */
#define GATT_OTSC_FILTER_BY_NAME_STARTS_WITH               (GattOtscObjectFilters) (0x0001)
#define GATT_OTSC_FILTER_BY_NAME_ENDS_WITH                 (GattOtscObjectFilters) (0x0002)
#define GATT_OTSC_FILTER_BY_NAME_CONTAINS                  (GattOtscObjectFilters) (0x0004)
#define GATT_OTSC_FILTER_BY_NAME_EXACT_MATCH               (GattOtscObjectFilters) (0x0008)
/* Object UUID filter */
#define GATT_OTSC_FILTER_BY_OBJECT_UUID_TYPE               (GattOtscObjectFilters) (0x0010)
/* Date filters */
#define GATT_OTSC_FILTER_BY_DATE_RANGE_CREATED             (GattOtscObjectFilters) (0x0020)
#define GATT_OTSC_FILTER_BY_DATE_RANGE_MODIFIED            (GattOtscObjectFilters) (0x0040)
/* Object size filters */
#define GATT_OTSC_FILTER_BY_CURRENT_SIZE_RANGE             (GattOtscObjectFilters) (0x0080)
#define GATT_OTSC_FILTER_BY_ALLOCATED_SIZE_RANGE           (GattOtscObjectFilters) (0x0100)
/* Marked object filter */
#define GATT_OTSC_FILTER_BY_MARKED_OBJECTS                 (GattOtscObjectFilters) (0x0200)

/*!
    @brief : Bitmask for the object properties set for an object at remote server 
*/
typedef uint32                                             GattOtscObjProperties;
#define GATT_OTSC_OBJ_PROPERTY_DELETE                      (GattOtscObjProperties) (0x00000001)
#define GATT_OTSC_OBJ_PROPERTY_EXECUTE                     (GattOtscObjProperties) (0x00000002)
#define GATT_OTSC_OBJ_PROPERTY_READ                        (GattOtscObjProperties) (0x00000004)
#define GATT_OTSC_OBJ_PROPERTY_WRITE                       (GattOtscObjProperties) (0x00000008)
#define GATT_OTSC_OBJ_PROPERTY_APPEND                      (GattOtscObjProperties) (0x00000010)
#define GATT_OTSC_OBJ_PROPERTY_TRUNCATE                    (GattOtscObjProperties) (0x00000020)
#define GATT_OTSC_OBJ_PROPERTY_PATCH                       (GattOtscObjProperties) (0x00000040)
#define GATT_OTSC_OBJ_PROPERTY_MARK                        (GattOtscObjProperties) (0x00000080)

/*!
    @brief Parameters used by the Initialization API
*/
typedef struct
{
     ConnectionId       cid;                 /* Connection ID.                */
     uint16             startHandle;         /* Start handle of OTS Server    */
     uint16             endHandle;           /* End handle of OTS Server      */
} GattOtscInitData;

/*!
    @brief  OTS Features characteristic value which determines the supported
           features of the Object Server in order to understand its capabilities.
*/
typedef struct
{
    uint32              otsSupportedFeatures[2];
} GattOtscSupportedFeatures;

/*!
    @brief Persistent data for each known OTS server device.

    Each OTS server device that is bonded can have the data associated against
    it so that re-connections are much faster by skipping the re-discovery.
*/
typedef struct
{
    GattOtscSupportedFeatures supportedFeatures;              /* OTS Features characteristic value [OACP Features(32bits) | OLCP Features(32 bits)] */
    uint16                    startHandle;                    /* Start handle of OTS service DB at server                   */
    uint16                    endHandle;                      /* End handle of OTS service DB at server                     */
    uint16                    otsFeatureHandle;               /* Handle of OTS feature characteristic                  */
    uint16                    objNameHandle;                  /* Handle of Object name characteristic                  */
    uint16                    objTypeHandle;                  /* Handle of Object type Characteristic                  */
    uint16                    objSizeHandle;                  /* Handle of Object size Characteristic                  */
    uint16                    objFirstCreatedHandle;          /* Handle of Object first created Characteristic         */
    uint16                    objLastModifiedHandle;          /* Handle of Object last modified Characteristic         */
    uint16                    objIdHandle;                    /* Handle of Object ID Characteristic                    */
    uint16                    objPropertiesHandle;            /* Handle of Object properties Characteristic            */
    uint16                    objActionControlPointHandle;    /* Handle of Object action control point Characteristic  */
    uint16                    objActionControlPointCCCDHandle;/* Handle of Object action control point Characteristic  */
    uint16                    objListControlPointHandle;      /* Handle of Object list control point Characteristic    */
    uint16                    objListControlPointCCCDHandle;  /* Handle of Object list control point Characteristic    */
    uint16                    objListFilterHandle1;           /* Handle of Object list filter Characteristic (first instance)  */
    uint16                    objListFilterHandle2;           /* Handle of Object list filter Characteristic (second instance) */
    uint16                    objListFilterHandle3;           /* Handle of Object list filter Characteristic (third instance)  */
    uint16                    objChangedHandle;               /* Handle of Object changed Characteristic                       */
    uint16                    objChangedCCCDHandle;           /* Handle of Object changed CCCD                         */
} GattOtscDeviceData;

/*!
    @brief Upstream message to use as an upstream CFM result of GattOtscInitReq API call.
*/
typedef struct
{
    GattOtscMessageId         id;            /* GATT_OTSC_INIT_CFM                        */
    ServiceHandle             svcHandle;     /* Reference handle for the client instance  */
    GattOtscSupportedFeatures suppFeatures;  /* Features supported by peer OTS server device (OACP & OLCP feature fields) */
    ConnectionId              cid;           /* GATT connection ID which app requested for*/
    CsrBtResultCode           resultCode;    /* Result code of the initialisation attempt */
    CsrBtSupplier             supplier;      /* Result supplier for above code            */
} GattOtscInitCfm;

/*!
    @brief Upstream message to use as an upstream CFM result of GattOtscTerminateReq API call.
*/
typedef struct
{
    GattOtscMessageId         id;            /* GATT_OTSC_TERMINATE_CFM                   */
    ServiceHandle             svcHandle;     /* Reference handle for the client instance  */
    GattOtscDeviceData        deviceData;    /* Peer characteristics handles discovered   */
    CsrBtResultCode           resultCode;    /* Result code of the termination attempt    */
    CsrBtSupplier             supplier;      /* Result supplier for above code            */
} GattOtscTerminateCfm;

/*!
    @brief Upstream message to use as an IND or CFM result of GattOtscRegisterForIndOrNotiReq API call.
    The IND message is sent to App only if App requests to register for more than one characteristics.
*/
typedef struct
{
    GattOtscMessageId         id;            /* GATT_OTSC_REGISTER_FOR_INDICATION_IND/CFM */
    ServiceHandle             svcHandle;     /* Reference handle for the client instance  */
    GattOtscCharacteristicsId characId;      /* Characteristic Identifier                 */
    CsrBtResultCode           resultCode;    /* Status of the initialization attempt      */
    CsrBtSupplier             supplier;      /* Result supplier                           */
} GattOtscRegisterForIndicationInd;

/*!
    @brief Upstream message to use as a CFM result of GattOtscRegisterForIndOrNotiReq API call.
    This message shows the end of registration request made by application.
*/
typedef GattOtscRegisterForIndicationInd GattOtscRegisterForIndicationCfm;

/*! @brief Upstream message is sent as a result of Object changed indication.
 */
typedef struct
{
    GattOtscMessageId         id;             /* GATT_OTSC_OBJECT_CHANGED_IND             */
    ServiceHandle             svcHandle;      /* Reference handle for the instance        */
    GattOtscObjectId          objectId;       /* Object ID on which change occurred       */
    GattOtscDeviceType        modifier;       /* Device[Another Client/Server] which made the change */
    GattOtscObjectChangeType  modification;   /* Bitmask for the nature of changes occurred at server */
} GattOtscObjectChangedInd;

/*! @brief Upstream message for select object confirmation.
 */
typedef struct
{
    GattOtscMessageId         id;             /* GATT_OTSC_SELECT_OBJECT_CFM              */
    ServiceHandle             svcHandle;      /* OTS client instance requested            */
    CsrBtResultCode           resultCode;     /* Status of the initialization attempt     */
    CsrBtSupplier             supplier;       /* Result supplier                          */
} GattOtscSelectObjectCfm;

/* @brief Upstream read object content CFM message
 * 
 * Note that, application must read the object content from the "data" pointer
 * it receives from "GattOtscReadObjectCfm" message,. and frees it as explained below.
 * In below ex, "cfm" is shown as the pointer of "GattOtscReadObjectCfm" message.
 * 
 * For VM platform:
 *     1."data" pointer is not the actual object content instead it is the Source
 *       of the object's content in stream. So it needs to be first typecasted back to Source type.
 *
 *       Source source = (Source) cfm->data;
 *
 *    2. Map the above Source to the data pointer(sourcePtr in below ex.) now
 *       which does hold the actual object's content.
 *
 *       const uint8 *sourcePtr = SourceMap(source);
 *
 *    3. Read the object content from data pointer (sourcePtr) for the data length
 *       sent through "dataLen" or copy those to the local place holder for parsing.
 *
 *    4. Once object content is read/consumed, free these by dropping from stream.
 *
 *       SourceDrop(source, cfm->dataLen);
 *
 * For other platform:
 *    "data" pointer holds the actual object content, no special handling is required.
 *     Make sure application must free the pointer once it is read/consumed.
 */
typedef struct
{
    GattOtscMessageId         id;             /* GATT_OTSC_READ_OBJECT_CFM                */
    ServiceHandle             svcHandle;      /* OTS client instance requested            */
    uint16                    dataLen;        /* Length of the data to be read/consumed   */
    uint8*                    data;           /* Data pointer which holds either
                                                 the Source of the object's content in Stream [for VM platform]
                                                 or
                                                 the actual object contents [For non-VM platforms]
                                                 Application must use and free the data as explained above */
    bool                      moreToCome;     /* more messages to come if TRUE            */
    CsrBtResultCode           resultCode;     /* Status of the read attempt               */
    CsrBtSupplier             supplier;       /* Result supplier                          */
} GattOtscReadObjectCfm;

/* @brief Upstream abort CFM message */
typedef struct
{
    GattOtscMessageId         id;             /* GATT_OTSC_ABORT_CFM                      */
    ServiceHandle             svcHandle;      /* OTS client instance requested            */
    CsrBtResultCode           resultCode;     /* Status of the abort attempt              */
    CsrBtSupplier             supplier;       /* Result supplier                          */
} GattOtscAbortCfm;

/* @brief Upstream Read Object Metadata CFM message */
typedef struct
{
    GattOtscMessageId         id;             /* GATT_OTSC_READ_OBJECT_METADATA_CFM         */
    ServiceHandle             svcHandle;      /* OTS client instance requested              */
    GattOtscCharacteristicsId characId;       /* Characteristic ID whose metadata requested */
    uint16                    valueLen;       /* Metadata value length                      */
    uint8*                    value;          /* Metadata value                             */
    CsrBtResultCode           resultCode;     /* Status of the read metadata attempt        */
    CsrBtSupplier             supplier;       /* Result supplier                            */
} GattOtscReadObjectMetadataCfm;

typedef struct
{
    CsrUtf8String            *startName;
    CsrUtf8String            *endName;
    CsrUtf8String            *nameContains;
    CsrUtf8String            *exactName;
} GattOtscFilterByNameInfo;

typedef struct
{
    CsrTime                   dateCreatedStart;
    CsrTime                   dateCreatedEnd;
    CsrTime                   dateModifiedStart;
    CsrTime                   dateModifiedEnd;
} GattOtscFilterByDateInfo;

typedef struct
{
    CsrUint32                 currentSizeStart;
    CsrUint32                 currentSizeEnd;
    CsrUint32                 allocatedSizeStart;
    CsrUint32                 allocatedSizeEnd;
} GattOtscFilterByObjSizeInfo;

/* @brief Upstream Filter Objects CFM message */
typedef struct
{
    GattOtscMessageId         id;             /* GATT_OTSC_FILTER_OBJECTS_CFM             */
    ServiceHandle             svcHandle;      /* Reference handle for the instance        */
    CsrBtResultCode           resultCode;     /* Status of the filter object attempt      */
    CsrBtSupplier             supplier;       /* Result supplier                          */
} GattOtscFilterObjectsCfm;

/* @brief Upstream Open OTS channel CFM message */
typedef struct
{
    GattOtscMessageId         id;             /* GATT_OTSC_OTS_CHANNEL_OPENED_CFM         */
    ServiceHandle             svcHandle;      /* Reference handle for the instance        */
    CsrBtConnId               btConnId;       /* L2cap connection ID for the OTS channel  */
    CsrBtResultCode           resultCode;     /* Status of the filter object attempt      */
    CsrBtSupplier             supplier;       /* Result supplier                          */
} GattOtscOtsChannelOpenedCfm;

/* @brief Upstream Close OTS channel IND message */
typedef struct
{
    GattOtscMessageId         id;             /* GATT_OTSC_OTS_CHANNEL_CLOSED_IND         */
    ServiceHandle             svcHandle;      /* Reference handle for the instance        */
    CsrBtConnId               btConnId;       /* L2cap connection ID for the OTS channel  */
    CsrBool                   locallyTerminated; /* locally or remote closed connection ? */
    CsrBtResultCode           resultCode;     /* Status of the filter object attempt      */
    CsrBtSupplier             supplier;       /* Result supplier                          */
} GattOtscOtsChannelClosedInd;

/*!
    @brief GATT OTS Client Service Initialization Request.

    @param appTask      The client task which will receive CFM message.
    \param initData     Configuration data for client initialisation.
    \param deviceData   Cached handles/data from previous connection with Peer Device OR
                        NULL if this is the first time this peer device has connected.

    NOTE: OTS sends GATT_OTSC_INIT_CFM message to appTask with the operation's result code.
*/
void GattOtscInitReq(AppTask appTask,
                     const GattOtscInitData   *initData,
                     const GattOtscDeviceData *deviceData);

/*!
    @brief GATT OTS Client Service Termination Request.
           Calling this function shall free all resources of the client service
           instance associated with the "svcHandle" requested.

    @param svcHandle    The service handle for this OTS Client Service instance.

    NOTE: OTS sends GATT_OTSC_TERMINATE_CFM message to the appTask with the operation's result code.
*/
void GattOtscTerminateReq(ServiceHandle svcHandle);

/*!
    @brief This API is used to write the client characteristic configuration of OTS related
           Control point characteristics on a remote device, i.e. to register/un-register for
           indication or notification at server.
           An error will be returned if the server does not support the indications/notifications.

    @param svcHandle    The service handle for this GATT Client Service.
    @param charsValMask Bitmask to enable/disable respective characteristics CCCDs

    NOTE: OTS sends GATT_OTSC_REGISTER_FOR_INDICATION_CFM message to the appTask with the operation's result code.
*/
void GattOtscRegisterForIndicationReq(ServiceHandle            svcHandle,
                                      GattOtscCharacValuesMask valMask);

/*!
    @brief Synchronous API to select an object either through object ID or any of the selection procedures requested.
           Selected object becomes the current object at server.
           OTS processes object selection operation only if this API returns TRUE.

    @param svcHandle    The service handle for this GATT Client Service
    @param objectId     Object ID for the object to select; used only if "selectOperation" is set to GATT_OTSC_SELECT_GOTO_OBJ.
    @param procedure    Procedure to follow for selecting an object; procedure can be : First/Last/Previous/Next/Goto

    NOTE: OTS sends GATT_OTSC_SELECT_OBJECT_CFM message to the appTask with the operation's result code.
    Note that OTS does not support multiple selection procedures simultaneously. Application must
    synchronize the requests.
*/
bool GattOtscSelectObjectReq(ServiceHandle          svcHandle,
                             const GattOtscObjectId objectId,
                             GattOtscObjListOpcode  opcode);

/*!
    @brief Synchronous API to read selected object's content from OTS Server device.
           To read complete object's content, application must send "offset" and "length"
           parameters as zeros. To read certain length of object's content from a certain offset,
           corresponding offset and length values to be passed.

           OTS processes this request further only if this API returns TRUE.

    @param svcHandle    The service handle for this GATT Client Service
    @param offset       Offset from where the client to start reading
    @param length       Number of bytes to be read from the offset value
    @param mtu          MTU to be used for LE-COC or L2CAP channel. Sent its value as zero if Synergy to auto configure
    @param connId       LE-CoC or L2cap connection ID to use if app has already created one. Send its value as zero otherwise.

NOTE: OTS sends GATT_OTSC_READ_OBJECT_CFM message with object content info to
      application for each successful piece of object's content OTS receives from OTS server device.
      Field "moreToCome" in this message denotes the status of data completion.
      If it is set to TRUE, it means there are still more data to receive otherwise
      complete data is received.
      Application may abort the ongoing read procedure anytime. Synergy sends
      GATT_OTSC_READ_OBJECT_CFM message with the result code GATT_OTSC_RESULT_CODE_OPERATION_ABORTED,
      followed by Abort CFM message. Refer to GattOtscAbortReq() API for more info.

      Note that, Application must read the object content from the "data" pointer it receives
      in "GattOtscReadObjectCfm" message,.and frees it as explained below.

      In below ex, "cfm" is shown as the pointer of "GattOtscReadObjectCfm" message.

      [For VM platform]
         1. "data" pointer is not the actual object content instead it is the "Source"
            of the object's content present in stream. So it needs to be first typecasted to "Source" type.

            Source dataSource = (Source) cfm->data;

         2. Map the above dataSource to the data pointer(sourcePtr in below ex.) now
            which does hold the actual object's content.

            const uint8 *dataPtr = SourceMap(dataSource);

         3. Read the object content from data pointer (dataPtr) for the data length
            sent through "dataLen" or copy those to the local place holder for parsing.

         4. Once object content is read/consumed, free these by dropping from stream.

            SourceDrop(dataSource, cfm->dataLen);

      [For non-VM platform]
         "data" pointer holds the actual object's content, so no special handling required.
          Make sure application frees the "data" pointer once it is read/consumed by calling
          CsrPmemFree().
 */
bool GattOtscReadObjectReq(ServiceHandle svcHandle,
                           uint32        offset,
                           uint32        length,
                           CsrBtConnId   connId);

/*!
    @brief Synchronous API to abort current OACP Read/Write operation in progress.
           OTS processes abort operation only if this API returns TRUE.

    @param svcHandle    The service handle for this GATT Client Service

    NOTE: OTS sends GATT_OTSC_ABORT_CFM message to the appTask with the operation's result code.
*/
bool GattOtscAbortReq(ServiceHandle svcHandle);

/* @brief Synchronous API to read current object's metadata for the requested
          characteristic from OTS Server device.
          OTS processes read metadata operation only if this API returns TRUE.

   @param svcHandle        The service handle for this GATT Client Service
          CharacId         Characteristic ID whose value or metadata to read

    NOTE: OTS sends GATT_OTSC_READ_OBJECT_METADATA_CFM message to the appTask
          with the operation's result code.
*/
bool GattOtscReadObjectMetadataReq(ServiceHandle             svcHandle,
                                   GattOtscCharacteristicsId CharacId);

/*!
    @brief Synchronous API to filter the objects at OTS server device.
           OTS processes filter objects operation only if this API returns TRUE.

    @param svcHandle       The service handle for this GATT Client Service
           filters         Filter bitmask of max three filters to be applied at server
           nameInfo        Name(NULL terminated) information for which filter to be applied
           dateInfo        Date information for which filter to be applied
           objSizeInfo     Object size information for which filter to be applied
           objectUuid      Obect's Gatt UUID type for which filter to be applied

    NOTE: OTS sends GATT_OTSC_FILTER_OBJECTS_CFM message to the appTask
          with the operation's result code. Filter date range is currently not supported.
*/
bool GattOtscFilterObjectsReq(ServiceHandle                svcHandle,
                              GattOtscObjectFilters        filters,         /* bitmask of max three filters to use */
                              GattOtscFilterByNameInfo    *nameInfo,
                              GattOtscFilterByDateInfo    *dateInfo,
                              GattOtscFilterByObjSizeInfo *objSizeInfo,
                              CsrBtUuid                    objectUuid);

/*!
    @brief Synchronous API to open object transfer channel with OTS server device.
           OTS performs this operation only if no OTS channel is already open and this API returns TRUE.
           Note: Application should call Read Object Content API only if the channel is successfully opened.

    @param svcHandle       The service handle for this GATT Client Service

    NOTE: OTS sends GATT_OTSC_OTS_CHANNEL_OPENED_CFM message to the appTask
          with the operation's result code.
*/
bool GattOtscOpenOtsChannelReq(ServiceHandle svcHandle);

/*!
    @brief Synchronous API to close object transfer channel with OTS server device.
           OTS performs this operation only if an OTS channel is open and this API returns TRUE.

    @param svcHandle       The service handle for this GATT Client Service

    NOTE: OTS sends GATT_OTSC_OTS_CHANNEL_CLOSED_IND message to the appTask
          with the operation's result code. Note that same message is sent if
          remote closes the object transfer channel.
*/
bool GattOtscCloseOtsChannelReq(ServiceHandle svcHandle);

/*!
    @brief Synchronous API to retrieve OTS device data(OTS characteristics handles &
           OTS Features characteristic value).

    Note that application must free the device data pointer this API returns.
*/
GattOtscDeviceData* GattOtscGetHandlesReq(ServiceHandle svcHandle);

#endif /* GATT_OTS_CLIENT_H */

